// tree数量
const TREE_NUM = 5;
// robocar数量
let ROBOCAR_NUM = 3;
// 界面尺寸设置
const WIDTH = 300;
const HEIGHT = 300;
// 随机id长度
const ID_LENGTH = 8;
// tree竖直方向运动速度
let TREE_VER_SPEED = 5;
// robocar竖直方向运动速度
let ROBOCAR_VER_SPEED = 3;
// robocar水平方向运动速度范围
const ROBOCAR_HOR_SPEED_LIST = [-2, 2];
// car水平方向运动速度
const HOR_SPEED = 5;
// 界面边距
const SIDE_GAP = 55;
// 可接收控制按键列表
const KEYLIST = ["w", "a", "s", "d"];

// 获取元素
const main = document.getElementsByClassName("main")[0];
const car = document.getElementById("car");
const score_el = document.getElementById("score");

// 分数
var score = 0;
// tree id列表
const tree_id_list = [];
// robocar id列表
const robocar_id_list = [];
// tree图片路径列表
const treeSrcList = [
  "./imgs/tree_1.png",
  "./imgs/tree_2.png",
  "./imgs/tree_3.png",
];
// robocar图片路径列表
const robocarSrcList = ["./imgs/robocar.png"];
// robocar初始位置可选列表
const robocarPosList = [SIDE_GAP + 15, SIDE_GAP + 135];
// 按键指令列表
const keys = [];

// 随机取值
// 参数： array || [num1, num2)
function getRandom(...arguments) {
  if (arguments.length === 2) {
    return (
      arguments[0] + Math.floor(Math.random() * (arguments[1] - arguments[0]))
    );
  } else if (arguments.length === 1 && Array.isArray(arguments[0])) {
    return arguments[0][Math.floor(Math.random() * arguments[0].length)];
  } else {
    console.log("输入参数不符合要求！");
  }
}
// 获取随机类名
// length 类名位数 sub_name 类名前缀
function getRandomIdName(length, sub_name) {
  const list = [
    [65, 91],
    [97, 123],
    [1, 10],
  ];

  let str = sub_name;
  for (let i = 0; i < length; i++) {
    let id = getRandom(0, 3);
    if (id === 2) {
      str += getRandom(...list[id]);
    } else {
      str += String.fromCharCode(getRandom(...list[id]));
    }
  }
  return str;
}

// 初始化主界面
function initMain() {
  main.style.height = HEIGHT + "px";
  main.style.width = WIDTH + "px";

  score_el.innerText = score;
}

// 初始化tree
// pos tree生成位置 "left" || "right"
// id tree唯一标识id
function initTree(pos, id) {
  let tree = document.createElement("img");
  tree.src = getRandom(treeSrcList);
  tree.classList.add(`tree-${pos}`);
  tree.classList.add("tree");
  tree.setAttribute("id", id);
  // tree.setAttribute("style", `top: 0px`);

  return tree;
}

function initRoboCar(id) {
  let robocar = document.createElement("img");
  robocar.src = getRandom(robocarSrcList);
  robocar.classList.add("robocar");
  robocar.setAttribute("id", id);
  robocar.setAttribute(
    "style",
    `top: 0px; left: ${getRandom(robocarPosList)}px`
  );

  return robocar;
}

// 根据当前tree数量，添加tree元素
function addTree() {
  if (tree_id_list.length < 2 * TREE_NUM && Math.random() > 0.9) {
    let treeIdName = getRandomIdName(ID_LENGTH, "tree-");
    const tree = initTree(getRandom(["left", "right"]), treeIdName);
    tree_id_list.push(treeIdName);
    main.appendChild(tree);
  }
}

// 更新tree位置，将超出下边界的tree元素移除
function updateTree() {
  for (let id of tree_id_list) {
    let el = document.getElementById(id);
    el.style.top = el.offsetTop + TREE_VER_SPEED + "px";
    if (el.offsetTop >= HEIGHT - 30) {
      main.removeChild(el);
      tree_id_list.splice(tree_id_list.indexOf(el.id), 1);
    }
  }
}

// 根据当前tree数量，添加tree元素
function addRoboCar() {
  if (robocar_id_list.length < ROBOCAR_NUM && Math.random() > 0.95) {
    let robocarIdName = getRandomIdName(ID_LENGTH, "robocar-");
    const robocar = initRoboCar(robocarIdName);
    robocar_id_list.push(robocarIdName);
    main.appendChild(robocar);
  }
}

// 更新robocar位置，robocar随机左右移动，将超出下边界的robocar元素移除
function updateRoboCar() {
  for (let id of robocar_id_list) {
    let el = document.getElementById(id);
    el.style.top = el.offsetTop + ROBOCAR_VER_SPEED + "px";
    const new_left = el.offsetLeft + getRandom(...ROBOCAR_HOR_SPEED_LIST);
    if (new_left >= SIDE_GAP && new_left <= WIDTH - SIDE_GAP) {
      el.style.left = new_left + "px";
    }
    if (el.offsetTop >= HEIGHT - 40) {
      main.removeChild(el);
      updateScore(1);
      robocar_id_list.splice(robocar_id_list.indexOf(el.id), 1);
    }
  }
}

// 更新分数
function updateScore(add) {
  score += add;
  score_el.innerText = score;
  // 随得分增长，robocar数量增大
  ROBOCAR_NUM += Math.floor(score / 50);
}

// 初始化按键监听
function initKeyListener() {
  document.addEventListener("keydown", (e) => {
    if (KEYLIST.includes(e.key) && keys.indexOf(e.key) === -1) {
      keys.push(e.key);
    }
  });
  document.addEventListener("keyup", (e) => {
    let id = keys.indexOf(e.key);
    if (id + 1) keys.splice(id, 1);
  });
}

// 检测两元素是否碰撞
function isCrash(ela, elb) {
  const left_bound = elb.offsetLeft - elb.offsetWidth / 2;
  const right_bound = elb.offsetLeft + elb.offsetWidth / 2;
  const hor_pos = ela.offsetLeft;
  // 宽度微调
  const width = ela.offsetWidth - 7;

  const up_bound = elb.offsetTop - elb.offsetHeight / 2;
  const down_bound = elb.offsetTop + elb.offsetHeight / 2;
  const ver_pos = ela.offsetTop;
  // 高度微调
  const height = ela.offsetHeight - 13;

  if (
    hor_pos + width / 2 < left_bound ||
    hor_pos - width / 2 > right_bound ||
    ver_pos + height / 2 < up_bound ||
    ver_pos - height / 2 > down_bound
  ) {
    return false;
  } else {
    return true;
  }
}

// 动画函数
function animate() {
  addTree();
  updateTree();
  addRoboCar();
  updateRoboCar();

  // 根据指令移动car
  for (let key of keys) {
    if (key === "a" && car.offsetLeft > SIDE_GAP) {
      car.style.left = car.offsetLeft - HOR_SPEED + "px";
    }
    if (key === "d" && car.offsetLeft < WIDTH - SIDE_GAP) {
      car.style.left = car.offsetLeft + HOR_SPEED + "px";
    }
    if (key === "w") {
      TREE_VER_SPEED = Math.min(8, TREE_VER_SPEED + 1);
      ROBOCAR_VER_SPEED = Math.min(6, ROBOCAR_VER_SPEED + 1);
    }
    if (key === "s") {
      TREE_VER_SPEED = Math.max(5, TREE_VER_SPEED - 1);
      ROBOCAR_VER_SPEED = Math.max(3, ROBOCAR_VER_SPEED - 1);
    }
  }

  for (let robocar_id of robocar_id_list) {
    let robocar = document.getElementById(robocar_id);
    if (isCrash(car, robocar)) {
      alert("game over!");
      return;
    }
  }

  requestAnimationFrame(animate);
}

initMain();
initKeyListener();
animate();
